<template>
    <div class="container">

        <div class="ai-avatar">
            <ai2 ref="aiAvatar" />
        </div>
        <div class="box">
            <div class="test-content">
                <div style="height: 15%;">
                    <p><strong>下面进行设备测试：</strong></p>
                </div>
                <div class="test1-mkf">
                    <div class=" test-inline-left">
                        <div style="display: flex;flex-direction: row;">
                            <p>麦克风：</p>
                            <el-form style="height: 16px;width: 80%;" ref="mainFormRef" :model="main_form"
                                :rules="rules">
                                <el-form-item prop="file">
                                    <el-select :disabled="voiceStatus" style="width:70%;position:relative;"
                                        v-model="main_form.chooseMicDeviceId" placeholder="请选择麦克风">
                                        <el-option v-for="item in Mic" :key="item.deviceId" :label="item.label"
                                            :value="item.deviceId">
                                        </el-option>
                                    </el-select>
                                </el-form-item>
                            </el-form>
                        </div>
                    </div>
                    <div class="test-inline-right">
                        <img class=" checkmark" :src="micCheckmarkSrc" alt="麦克风状态">
                    </div>
                </div>
                <div class="test2-camera">
                    <div class="test-inline-left">
                        <p>摄像头：</p>
                        <div style=" padding: 0 70px;">
                            <video id="videoCamera" autoplay></video>
                            <canvas style="display: none" id="canvasCamera" :width="videoWidth"
                                :height="videoHeight"></canvas>
                        </div>
                    </div>
                    <div class="test-inline-right">
                        <img class=" checkmark" :src="cameraCheckmarkSrc" alt="摄像头状态">
                    </div>
                </div>
                <div class="test3-net">
                    <div class="test-inline-left">
                        <p>网络延迟： {{ lastDelay }} ms</p>
                    </div>
                    <div class="test-inline-right">
                        <img class=" checkmark" :src="netCheckmarkSrc" alt="网络状态">
                    </div>
                </div>
            </div>
            <div class="button-area">
                <button class="next-button" @click="jumpToNext()">下一步 ></button>
            </div>
        </div>
    </div>

</template>

<script>
import ai2 from '@/views/aii/views/avatardemo.vue'
export default {
    components: { ai2 },
    data() {
        return {
            videoWidth: 200,
            videoHeight: 150,
            cameraList: [{ id: "", label: "摄像头1" }],
            currentCamera: "",
            imgSrc: "",
            recorder: '',
            voiceStatus: false, // 是否正在录音
            main_form: {
                chooseMicDeviceId: '', // 选择的麦克风id
            },
            Mic: [], // 可选择的麦克风
            rules: {
                file: [
                    { required: true, message: "不能为空", trigger: "blur" },
                ],
            },
            RMSList: [
                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                0, 0, 0, 0,
            ],
            netCheckmarkSrc: require('../src/tick-grey.png'), // 初始状态的图片路径
            micCheckmarkSrc: require('../src/tick-grey.png'), // 初始状态的麦克风图片路径
            cameraCheckmarkSrc: require('../src/tick-grey.png'), // 初始状态的摄像头图片路径
            strURL: '',           // 测试目标URL
            bolIsRunning: false,  // 测试状态
            intTimerID: null,     // 超时计时器ID
            bolIsTimeout: false,  // 是否超时
            objIMG: null,         // 图片对象，用来测试请求
            lastDelay: '-',       // 最新一次ping时间
            intTimeout: 1000,     // 单次请求超时1秒
            intervalID: null,     // 定时器ID（2秒ping一次）
            intStartTime: 0,
            interviewMode: ''
        };
    },

    created() {
        this.$nextTick(() => {
            this.$refs.aiAvatar.startAll()
            this.$refs.aiAvatar.startVirtualHuman()
            this.$refs.aiAvatar.sendTextToAvatar()
        }),
            this.interviewMode = this.interviewModeFromStore;
        console.log('当前面试模式:', this.interviewMode);
    },
    computed: {
        interviewModeFromStore() {
            return this.$store.getters['scene/getInterviewMode'];
        }
    },

    mounted() {
        // 获取摄像头列表
        this.getDevices().then(res => {
            if (res.length) {
                this.cameraList = res;
            }
            this.currentCamera = this.cameraList[0].id;
            this.main();
            this.getMic();
        });
        this.strURL = window.location.origin + '/favicon.ico'; // 访问稳定资源
        this.bolIsRunning = true;
        this.objIMG = new Image();
        this.objIMG.onload = this.objIMG.onerror = () => {
            clearTimeout(this.intTimerID);
            if (!this.bolIsRunning || this.bolIsTimeout) return;

            const delay = Date.now() - this.intStartTime;
            this.lastDelay = delay;
            if (delay < 1000) {
                this.netCheckmarkSrc = require('../src/tick-finish.png'); // 网络正常，对号变绿
            } else {
                this.netCheckmarkSrc = require('../src/tick-grey.png'); // 网络异常，对号变灰
            }
        };
        this.startPeriodicPing();
    },
    beforeUnmount() {
        this.bolIsRunning = false;
        clearTimeout(this.intTimerID);
        clearInterval(this.intervalID);
    },

    methods: {
        main() {
            this.thisCanvas = document.getElementById("canvasCamera");
            this.thisContext = this.thisCanvas.getContext("2d");
            this.thisVideo = document.getElementById("videoCamera");
            this.enableCamera(this.currentCamera);
        },
        getDevices() {
            return new Promise((resolve, reject) => {
                if (!navigator.mediaDevices || !navigator.mediaDevices.enumerateDevices) {
                    window.alert("不支持 mediaDevices.enumerateDevices()");
                }
                navigator.mediaDevices
                    .enumerateDevices()
                    .then(devices => {
                        let cameraList = [];
                        devices.forEach((device, index) => {
                            // 获取摄像头外设 videoinput
                            if (device.kind && device.kind === "videoinput") {
                                if (device.deviceId) {
                                    cameraList.push({
                                        id: device.deviceId,
                                        label: device.label
                                    });
                                }
                            }
                        });
                        resolve(cameraList);
                    })
                    .catch(err => {
                        console.log(err.name + ": " + err.message);
                        reject();
                    });
            });
        },
        /**
         * @desc 获取摄像头权限 getUserMedia
         * deviceId	getDevices()函数获取的设备id
         * success  调用成功的回调函数
         * error	调用失败的回调函数
         */
        getUserMedia(deviceId, success, error) {
            const constraints = {
                audio: false,
                video: {
                    width: this.videoWidth,
                    height: this.videoHeight,
                    transform: "scaleX(-1)",
                    deviceId: deviceId
                }
            };
            if (navigator.mediaDevices.getUserMedia) {
                //最新的标准API
                navigator.mediaDevices
                    .getUserMedia(constraints)
                    .then(success)
                    .catch(error);
            } else if (navigator.webkitGetUserMedia) {
                //webkit核心浏览器
                navigator.webkitGetUserMedia(constraints, success, error);
            } else if (navigator.mozGetUserMedia) {
                //firfox浏览器
                navigator.mozGetUserMedia(constraints, success, error);
            } else if (navigator.getUserMedia) {
                //旧版API
                navigator.getUserMedia(constraints, success, error);
            }
        } /** @desc 摄像头使能封装 */,
        enableCamera(deviceId) {
            this.getUserMedia(
                deviceId,
                stream => {
                    if ("srcObject" in this.thisVideo) {
                        this.thisVideo.srcObject = stream;
                    } else {
                        // 避免在新的浏览器中使用它，新浏览器正在被弃用。没有开启摄像头权限或浏览器版本不兼容
                        this.thisVideo.src = window.URL.createObjectURL(stream);
                    }
                    this.thisVideo.onloadedmetadata = e => {
                        this.thisVideo.play();
                        this.cameraCheckmarkSrc = require('../src/tick-finish.png'); // 摄像头正常工作，对号变绿
                    };
                },
                error => {
                    console.log(`访问用户媒体设备失败${error.name}, ${error.message}`);
                    alert("摄像头打开失败，请检查摄像头并点击浏览器地址栏右侧的摄像头标志进行开启设置");
                    this.cameraCheckmarkSrc = require('../src/tick-grey.png'); // 摄像头失败，对号变灰
                }
            );
        },
        // 获取当前页面可以选择的麦克风
        getMic() {
            let that = this;
            if (navigator.mediaDevices && navigator.mediaDevices.getUserMedia) {
                // 弹框获取麦克风
                navigator.mediaDevices.getUserMedia({ audio: true }).then((stream) => {
                    navigator.mediaDevices.enumerateDevices().then(function (devices) {
                        devices.forEach(function (device) {
                            console.log(devices);
                            if (device.kind === 'audioinput') { // 麦克风
                                if (device.deviceId != 'default' && device.deviceId != 'communications') {
                                    that.Mic.push(device)
                                }
                            }
                        });
                        if (that.Mic.length > 0) {
                            that.micCheckmarkSrc = require('../src/tick-finish.png'); // 有可用麦克风，对号变绿
                        }
                    })
                    stream.getTracks().forEach(track => track.stop());
                })
            }

        },
        // 获取音量值大小
        getVoice() {
            const audioContext = new (window.AudioContext || window.webkitAudioContext)()
            // 将麦克风的声音输入这个对象
            const mediaStreamSource = audioContext.createMediaStreamSource(this.stream)
            // 创建分析节点
            const analyserNode = audioContext.createAnalyser()
            // 连接节点
            mediaStreamSource.connect(analyserNode)
            // 可以实时听到麦克风采集的声音
            // analyserNode.connect(audioContext.destination)

            // 获取音量数据
            const dataArray = new Uint8Array(analyserNode.frequencyBinCount);

            function getVolume() {
                analyserNode.getByteFrequencyData(dataArray);
                let sum = 0;
                for (let i = 0; i < dataArray.length; i++) {
                    sum += dataArray[i];
                }
                // 计算平均音量
                const averageVolume = sum / dataArray.length;
                return averageVolume;
            }

            // 每隔一段时间获取一次音量
            this.timer1 = setInterval(() => {
                const volume = getVolume();
                console.log('音量:', Math.round(volume));
                // 在这里可以根据需要进行相应的处理
                this.RMSList.unshift(Math.round(volume));
                this.RMSList.value.pop();
            }, 100);
        },

        // 每timeSlice执行一次
        sendData(blob) {
            var BB = new Blob([blob], { 'type': 'audio/wav; codecs=opus' })
            // var audioURL = window.URL.createObjectURL(BB)

            // 播放
            // const audio = document.createElement('audio')
            // audio.controls = true // 音频是否显示控件
            // audio.src = audioURL
            // audio.play()

            // 下载
            // let a = document.createElement("a");
            // a.href = audioURL;
            // a.download = '测试';
            // a.click();
            // // 释放这个临时的对象url
            // window.URL.revokeObjectURL(audioURL);

            let file = new window.File([BB], '测试.wav')
            console.log(file);
        },
        // // 拍照
        // handlePhotograph() {
        //     this.thisContext.drawImage(this.thisVideo, 0, 0, 300, 200);
        //     // 获取图片base64链接;
        //     this.imgSrc = this.thisCanvas.toDataURL("image/png", 0.7);
        // }
        startPeriodicPing() {
            this.ping();
            this.intervalID = setInterval(() => {
                if (!this.bolIsRunning) {
                    clearInterval(this.intervalID);
                    return;
                }
                this.ping();
            }, 2000);
        },
        ping() {
            this.intStartTime = Date.now();
            this.bolIsTimeout = false;
            this.objIMG.src = this.strURL + '?t=' + this.intStartTime;

            clearTimeout(this.intTimerID);
            this.intTimerID = setTimeout(() => {
                this.timeout();
            }, this.intTimeout);
        },
        timeout() {
            if (!this.bolIsRunning) return;
            this.bolIsTimeout = true;
            console.log('请求超时');
            this.objIMG.src = ''; // 触发错误，强制重新请求
        },
        jumpToNext() {
            if (this.interviewMode == 'practice') {
                this.$router.push({ path: '/simulate' });
            } else {
                this.$router.push({ path: '/simulate2' });
            }
            this.$refs.aiAvatar.closeAll()
        },
    },
};
</script>

<style lang="scss" scoped>
.container {
    display: flex;
    height: 100%;
    gap: 20px;
    padding: 40px;
    box-sizing: border-box;
}

/* 左侧数字人头像 */
.ai-avatar {
    flex: 1;
    display: flex;
    justify-content: center;
    align-items: center;
    border-radius: 12px;
    box-shadow: 0 4px 16px rgba(0, 0, 0, 0.15);
    height: 100%;
    width: 33%;
}


/* 右侧内容框 */
.box {
    flex: 2;
    background-color: #ffffff;
    border: 1px solid #dcdfe6;
    border-radius: 12px;
    padding: 22px;
    display: flex;
    flex-direction: column;
    justify-content: space-between;
    box-shadow: 0 4px 20px rgba(0, 0, 0, 0.08);
    height: 100%;
    width: 66%;
}

.test-content {
    height: 90%;
    font-size: 16px;
    color: #333;
    margin-bottom: 16px;
    white-space: pre-wrap;
    display: flex;
    flex-direction: column;
    // grid-template-columns: 72% 18%;
    // grid-template-rows: 18% 45% 27%;
    // grid-row-gap: 20px;
    // grid-column-gap: 20px;
    align-items: start;
}

.test-inline-left {
    width: 80%;
    height: 100%;
}

.test-inline-right {
    width: 20%;
    height: 100%;
    /* 使用 Flexbox 布局 */
    display: flex;
    /* 水平居中 */
    justify-content: center;
    /* 垂直居中 */
    align-items: start;
}

.test1-mkf {
    height: 20%;
    width: 100%;
    display: flex;
    flex-direction: row;
}

.test2-camera {
    height: 50%;
    width: 100%;
    display: flex;
    flex-direction: row;
}

.test3-net {
    height: 10%;
    width: 100%;
    display: flex;
    flex-direction: row;
}

.button-area {
    display: flex;
    justify-content: flex-end;
    height: 10%;
}

.next-button {
    padding: 10px 20px !important;
    font-size: 16px !important;
    background-color: #409eff !important;
    color: #fff !important;
    border: none !important;
    border-radius: 6px !important;
    cursor: pointer !important;
}

.pre-line {
    white-space: pre-wrap;
    line-height: 1.5;
}

.checkmark {
    width: 24px;
    height: 24px;
}
</style>
